package student;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.*;
import java.util.*;

@WebServlet("/StudentSubmitExamServlet")
public class StudentSubmitExamServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession();
        response.setContentType("application/json");
        PrintWriter out = response.getWriter();

        // 检查会话有效性
        if (session.getAttribute("student_id") == null) {
            sendJsonError(response, "会话已过期，请重新登录", 401, out);
            return;
        }

        // 获取请求参数
        int examId = Integer.parseInt(request.getParameter("exam_id"));
        int studentId = (Integer) session.getAttribute("student_id");

        try {
            Connectmysql conn = new Connectmysql(
                    "jdbc:mysql://localhost:3306/exam",
                    "root", "root", "com.mysql.cj.jdbc.Driver");

            if (!conn.open()) {
                sendJsonError(response, "数据库连接失败", 500, out);
                return;
            }

            // 1. 获取考试题目和正确答案
            Map<Integer, String> correctAnswers = new HashMap<>();
            Map<Integer, Double> questionScores = new HashMap<>();
            double totalScore = 0;

            String sql = "SELECT q.question_id, q.correct_answer, q.score " +
                    "FROM exam_question eq " +
                    "JOIN question q ON eq.question_id = q.question_id " +
                    "WHERE eq.exam_id = ?";

            ResultSet rs = conn.executeSql(sql, new Object[]{examId});
            while (rs.next()) {
                int questionId = rs.getInt("question_id");
                correctAnswers.put(questionId, rs.getString("correct_answer"));
                questionScores.put(questionId, rs.getDouble("score"));
            }

            if (correctAnswers.isEmpty()) {
                sendJsonError(response, "未找到考试题目", 404, out);
                return;
            }

            // 2. 计算分数
            double studentScore = 0;
            int correctCount = 0;

            for (int questionId : correctAnswers.keySet()) {
                String answerParam = request.getParameter("answer_" + questionId);
                String correctAnswer = correctAnswers.get(questionId);

                if (answerParam != null && answerParam.equals(correctAnswer)) {
                    studentScore += questionScores.getOrDefault(questionId, 0.0);
                    correctCount++;
                }
            }

            // 3. 获取课程ID
            int courseId = 0;
            sql = "SELECT course_id FROM exam WHERE exam_id = ?";
            rs = conn.executeSql(sql, new Object[]{examId});
            if (rs.next()) {
                courseId = rs.getInt("course_id");
            }

            // 4. 判断是否通过 (假设60分及格)
            boolean isPassed = (studentScore >= 60);

            // 5. 存储成绩
            sql = "INSERT INTO student_score (student_id, exam_id, course_id, score, is_passed) " +
                    "VALUES (?, ?, ?, ?, ?) " +
                    "ON DUPLICATE KEY UPDATE score = VALUES(score), is_passed = VALUES(is_passed)";

            int result = conn.executeSqlUpdate(sql, new Object[]{
                    studentId, examId, courseId, studentScore, isPassed ? 1 : 0
            });

            if (result > 0) {
                // 准备JSON结果
                Map<String, Object> jsonResponse = new LinkedHashMap<>();
                jsonResponse.put("success", true);
                jsonResponse.put("score", studentScore);
                jsonResponse.put("correctCount", correctCount);
                jsonResponse.put("totalQuestions", correctAnswers.size());
                jsonResponse.put("isPassed", isPassed);

                session.removeAttribute("currentExamId");

                out.print(mapToJson(jsonResponse));
            } else {
                sendJsonError(response, "成绩保存失败", 500, out);
            }
        } catch (Exception e) {
            sendJsonError(response, "提交考试失败: " + e.getMessage(), 500, out);
            e.printStackTrace();
        } finally {
            out.flush();
        }
    }

    private void sendJsonError(HttpServletResponse response, String message, int statusCode, PrintWriter out) {
        response.setStatus(statusCode);
        Map<String, Object> errorResponse = new HashMap<>();
        errorResponse.put("success", false);
        errorResponse.put("message", message);
        out.print(mapToJson(errorResponse));
    }

    private String mapToJson(Map<String, Object> map) {
        StringBuilder json = new StringBuilder("{");
        boolean first = true;

        for (Map.Entry<String, Object> entry : map.entrySet()) {
            if (!first) json.append(",");

            json.append("\"").append(entry.getKey()).append("\":");

            if (entry.getValue() instanceof String) {
                json.append("\"").append(escapeJson(entry.getValue().toString())).append("\"");
            } else if (entry.getValue() instanceof Boolean || entry.getValue() instanceof Number) {
                json.append(entry.getValue());
            } else {
                json.append("\"").append(escapeJson(entry.getValue().toString())).append("\"");
            }

            first = false;
        }

        json.append("}");
        return json.toString();
    }

    private String escapeJson(String input) {
        if (input == null) return "";
        return input.replace("\\", "\\\\")
                .replace("\"", "\\\"")
                .replace("\b", "\\b")
                .replace("\f", "\\f")
                .replace("\n", "\\n")
                .replace("\r", "\\r")
                .replace("\t", "\\t");
    }
}